﻿using Common;
using MahApps.Metro.Controls;
using MahApps.Metro.Controls.Dialogs;
using Microsoft.Win32;
using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Media;
using LicenseContext = OfficeOpenXml.LicenseContext;

namespace KangboMcuTest
{
    internal class TestResultConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            bool? result = value as bool?;
            if (parameter.ToString() == "color")
            {
                if (result == true)
                {
                    return Brushes.Green;
                }
                else if (result == false)
                {
                    return Brushes.Red;
                }
                else
                {
                    return Brushes.Gray;
                }
            }
            else
            {
                if (result == true)
                {
                    return "OK";
                }
                else if (result == false)
                {
                    return "NG";
                }
                else
                {
                    return "WAITTING";
                }
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }
    }

    internal class BurnViewModel : NotifyBase
    {
        public ObservableCollection<FlashData> FileFlashData { get; set; }
        public ObservableCollection<FlashData> RegisterFlashData { get; set; }

        public BurnViewModel()
        {
            BurnOk = null;
            Port = "COM5";
            Baud = 500000;
            McuAddress = 1;
            FileFlashData = new ObservableCollection<FlashData>();
            RegisterFlashData = new ObservableCollection<FlashData>();

            SelectFileCommand = new CommandBase(SelectFile);
            BurnCommand = new CommandBase(Burn);
            CompareCommand = new CommandBase(Compare);
        }

        int i = 0;

        private void Compare(object obj)
        {
            Log = "-------" + i++;
            BurnOk = null;
            RegisterFlashData.Clear();
            FileFlashData.Clear();
            Thread.Sleep(10);

            var mwin = Application.Current.MainWindow as MetroWindow;
            if (Port is null | Port == string.Empty)
            {
                mwin.ShowMessageAsync("提示", "串口不能为空");
                return;
            }
            if (EEPRomPath is null | EEPRomPath == string.Empty)
            {
                mwin.ShowMessageAsync("提示", "烧录文件不能为空");
                return;
            }
            if (SN == null | SN == string.Empty)
            {
                mwin.ShowMessageAsync("提示", "SN码不能为空");
                return;
            }
            Task.Run(() =>
            {
                try
                {
                    bool ret = TPS929120.WriteFlash(Port, EEPRomPath, McuAddress, true);

                    Application.Current.Dispatcher.Invoke(new Action(() =>
                    {
                        for (int i = 0; i < TPS929120.listReadRegReturn.Count; i++)
                        {
                            RegisterFlashData.Add(new FlashData { Index = i, Address = TPS929120.listReadRegReturn[i][2].ToString("X2"), Data = TPS929120.listReadRegReturn[i][4].ToString("X2") });
                            FileFlashData.Add(new FlashData { Index = i, Address = TPS929120.listWriteRegCmd[i + 10][2].ToString("X2"), Data = TPS929120.listWriteRegCmd[i + 10][3].ToString("X2") });
                        }
                    }));
                    if (ret == true)
                    {
                        BurnOk = true;
                        TestResult result = new TestResult
                        {
                            SN = this.SN,
                            Action = "数据校对",
                            BurnTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                            Result = "OK"
                        };
                        NoteTestRet(result);
                    }
                    else
                    {
                        BurnOk = false;
                    }
                    foreach (var item in TPS929120.listErr)
                    {
                        Log = item.ToString();
                    }
                }
                catch (Exception ex)
                {
                    Log = ex.Message;
                }
            });
        }

        private void NoteTestRet(TestResult result)
        {
            string dir = "Data";
            string path = @$"./Data/{DateTime.Now.ToString("yyyyMMdd")}.xlsx";
            string sample = "sample.xlsx";
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            if (!File.Exists(path))
            {
                File.Copy(sample, path);
            }
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
            // 打开 Excel 文件
            using (ExcelPackage package = new ExcelPackage(new FileInfo(path)))
            {
                ExcelWorkbook workbook = package.Workbook;
                ExcelWorksheets worksheets = workbook.Worksheets;

                ExcelWorksheet worksheet1 = workbook.Worksheets[0];

                int rowTotal = worksheet1.Dimension.Rows;
                int colTotal = worksheet1.Dimension.Columns;

                worksheet1.Cells.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
                //worksheet1.Cells.AutoFitColumns();

                worksheet1.Cells[rowTotal + 1, 1].Value = result.SN;
                worksheet1.Cells[rowTotal + 1, 2].Value = result.Action;
                worksheet1.Cells[rowTotal + 1, 3].Value = result.BurnTime;
                worksheet1.Cells[rowTotal + 1, 4].Value = result.Result;

                package.Save();
            }
        }

        private string _log;

        public string Log
        {
            get { return _log; }
            set
            {
                Application.Current.Dispatcher.Invoke(new Action(() =>
                {
                    _log = value;
                    this.DoNotify();
                }));
                Console.WriteLine(value);
            }
        }

        private void Burn(object obj)
        {
            Log = "-------" + i++;
            BurnOk = null;
            RegisterFlashData.Clear();
            FileFlashData.Clear();
            Thread.Sleep(10);
            var mwin = Application.Current.MainWindow as MetroWindow;
            if (Port is null | Port == string.Empty)
            {
                mwin.ShowMessageAsync("提示", "串口不能为空");
                return;
            }
            if (EEPRomPath is null | EEPRomPath == string.Empty)
            {
                mwin.ShowMessageAsync("提示", "烧录文件不能为空");
                return;
            }
            if (SN == null | SN == string.Empty)
            {
                mwin.ShowMessageAsync("提示", "SN码不能为空");
                return;
            }
            Task.Run(() =>
            {
                try
                {
                    bool ret = TPS929120.WriteFlash(Port, EEPRomPath, McuAddress, false);

                    Application.Current.Dispatcher.Invoke(new Action(() =>
                    {
                        for (int i = 0; i < TPS929120.listReadRegReturn.Count; i++)
                        {
                            RegisterFlashData.Add(new FlashData { Index = i, Address = TPS929120.listReadRegReturn[i][2].ToString("X2"), Data = TPS929120.listReadRegReturn[i][4].ToString("X2") });
                            FileFlashData.Add(new FlashData { Index = i, Address = TPS929120.listWriteRegCmd[i + 10][2].ToString("X2"), Data = TPS929120.listWriteRegCmd[i + 10][3].ToString("X2") });
                        }
                    }));
                    if (ret == true)
                    {
                        BurnOk = true;
                        TestResult result = new TestResult
                        {
                            SN = this.SN,
                            Action = "烧录并校对",
                            BurnTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                            Result = "OK"
                        };
                        NoteTestRet(result);
                    }
                    else
                    {
                        BurnOk = false;
                    }
                    foreach (var item in TPS929120.listErr)
                    {
                        Log = item.ToString();
                    }
                }
                catch (Exception ex)
                {
                    Log = ex.Message;
                }
            });
        }

        private void SelectFile(object obj)
        {
            // 创建一个新的 OpenFileDialog 对象
            OpenFileDialog openFileDialog = new OpenFileDialog();

            // 设置对话框的标题
            openFileDialog.Title = "选择烧录文件";

            openFileDialog.RestoreDirectory = true;

            // 设置过滤器，限制可以选择的文件类型（可选）
            openFileDialog.Filter = "烧录文件 (*.csv)|*.csv|所有文件 (*.*)|*.*";

            // 打开对话框并检查用户是否点击了 "打开" 按钮
            if (openFileDialog.ShowDialog() == true)
            {
                // 用户已选择文件，您可以执行所需的操作
                string selectedFilePath = openFileDialog.FileName;
                Console.WriteLine("选择的文件路径：" + selectedFilePath);
                EEPRomPath = selectedFilePath;
            }
            BurnOk = null;
        }

        private string _port;

        public string Port
        {
            get { return _port; }
            set
            {
                _port = value;
                this.DoNotify();
            }
        }

        private int _baud;

        public int Baud
        {
            get { return _baud; }
            set
            {
                _baud = value;
                this.DoNotify();
            }
        }

        private int _mcuAddress;

        public int McuAddress
        {
            get { return _mcuAddress; }
            set
            {
                _mcuAddress = value;
                this.DoNotify();
            }
        }

        private string _sn;

        public string SN
        {
            get { return _sn; }
            set
            {
                _sn = value;
                this.DoNotify();
            }
        }

        private string _eepromPath;

        public string EEPRomPath
        {
            get { return _eepromPath; }
            set
            {
                _eepromPath = value;
                this.DoNotify();
            }
        }

        private bool? _burnOK;

        public bool? BurnOk
        {
            get { return _burnOK; }
            set
            {
                _burnOK = value;
                this.DoNotify();
            }
        }

        public CommandBase SelectFileCommand { get; set; }
        public CommandBase BurnCommand { get; set; }
        public CommandBase CompareCommand { get; set; }
    }
}